package drds.plus.executor.sequence_manager;


import drds.plus.common.lifecycle.AbstractLifecycle;
import drds.plus.sequence.Sequence;
import drds.plus.sequence.SequenceException;
import drds.plus.sql_process.sequence.ISequenceManager;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

import java.util.Map;
import java.util.TreeMap;

@Slf4j
public class SequenceManager extends AbstractLifecycle implements ISequenceManager {

    public Logger log() {
        return log;
    }

    private Map<String, Sequence> sequenceNameToSequenceMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
    private DbSequenceManager dbSequenceManager = new DbSequenceManager();

    public void doInit() {
    }

    public Long nextValue(String sequenceName) {
        Sequence sequence = getSequence(sequenceName);
        if (sequence == null) {
            throw new RuntimeException("ErrorCode.ERR_MISS_SEQUENCE" + sequenceName);
        }

        try {
            return sequence.nextValue();
        } catch (SequenceException e) {
            throw new RuntimeException("ErrorCode.ERR_SEQUENCE_NEXT_VALUE");
        }
    }

    public Long nextValue(String sequenceName, int batchSize) {
        Sequence sequence = getSequence(sequenceName);
        if (sequence == null) {
            throw new RuntimeException("ErrorCode.ERR_MISS_SEQUENCE, seqName");
        }

        try {
            return sequence.nextValue(batchSize);
        } catch (SequenceException e) {
            throw new RuntimeException("ErrorCode.ERR_SEQUENCE_NEXT_VALUE, e, seqName, e.getMessage()");
        }
    }

    protected Sequence getSequence(String name) {
        Sequence sequence = this.sequenceNameToSequenceMap.get(name);
        if (sequence != null) {
            return sequence;
        } else {
            sequence = dbSequenceManager.getSequence(name);
            sequenceNameToSequenceMap.put(name, sequence);
        }
        return sequence;
    }

    protected void doDestroy() throws RuntimeException {
        sequenceNameToSequenceMap.clear();
        dbSequenceManager.doDestroy();

    }


}
